package br.org.acessobrasil.portal.action.itemConteudo;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import br.com.goals.tableedit.util.Conversor;
import br.org.acessobrasil.portal.action.Super;
import br.org.acessobrasil.portal.controle.AsesCliente;
import br.org.acessobrasil.portal.controle.SecurityManager;
import br.org.acessobrasil.portal.facade.ItemConteudoFacade;
import br.org.acessobrasil.portal.modelo.Arquivo;
import br.org.acessobrasil.portal.modelo.Conteudo;
import br.org.acessobrasil.portal.modelo.ConteudoFormatado;
import br.org.acessobrasil.portal.modelo.InformacaoTipoConteudo;
import br.org.acessobrasil.portal.modelo.ItemConteudo;
import br.org.acessobrasil.portal.modelo.Usuario;
import br.org.acessobrasil.portal.persistencia.ItemConteudoDaoTemp;
import br.org.acessobrasil.portal.util.LoginInterceptor;
import br.org.acessobrasil.portal.vista.FormularioItemConteudo;
import br.org.acessobrasil.portal.vista.GeraRelatorio;

public abstract class BaseItemConteudo extends Super implements ItemConteudoInterface{
	private static final long serialVersionUID = -7643624944010160482L;
	private static Logger logger = Logger.getLogger(BaseItemConteudo.class);
	private String btnFindAndReplace;
	protected int escolhendo = 0;
	protected InformacaoTipoConteudo informacaoTipoConteudo;
	protected Arquivo arquivo;
	protected String btnSalvarPublicar;
	private ItemConteudoFacade itemConteudoFacade;
	
	private String procurar;
	private String substituir;
	
	/**
	 * Caso o usuario queira que o sistema tente acessibilizar o conteudo automaticamente
	 */
	private String btnAcessibilizar = null;
	
	public ItemConteudoFacade getItemConteudoFacade(){
		if(itemConteudoFacade==null){
			itemConteudoFacade =(ItemConteudoFacade)getBean("itemConteudoFacade"); 
		}
		return itemConteudoFacade;
	}
	
	public void setItemConteudoFacade(ItemConteudoFacade itemConteudoFacade) {
		this.itemConteudoFacade = itemConteudoFacade;
	}
	
	@Override
	public String getBtnSalvarPublicar() {
		return btnSalvarPublicar;
	}
	
	@Override
	public void setBtnSalvarPublicar(String btnSalvarPublicar) {
		this.btnSalvarPublicar = btnSalvarPublicar;
	}
	
	public InformacaoTipoConteudo getInformacaoTipoConteudo() {
		return informacaoTipoConteudo;
	}
	
	public void setInformacaoTipoConteudo(InformacaoTipoConteudo informacaoTipoConteudo) {
		this.informacaoTipoConteudo = informacaoTipoConteudo;
	}
	
	public Arquivo getArquivo() {
		return arquivo;
	}
	
	public void setArquivo(Arquivo arquivo) {
		this.arquivo = arquivo;
	}
	
	public int getEscolhendo() {
		return escolhendo;
	}
	
	public void setEscolhendo(int escolhendo) {
		this.escolhendo = escolhendo;
	}
	
	protected void montarFormularioArquivoEscolhido(String action) throws Exception {
		//Colocar o arquivo no item de conteudo
		ItemConteudo itemConteudo = getItemConteudoDaoTemp().getItemConteudo(getItemConteudo().getNuItemConteudo());
		if(informacaoTipoConteudo!=null && arquivo!=null){
			for(ConteudoFormatado conteudo :itemConteudo.getListConteudoFormatado()){
				logger.debug("conteudo.getNuInformacaoTipoConteudo() = " + conteudo.getNuInformacaoTipoConteudo());
				logger.debug("informacaoTipoConteudo.getNuInformacaoTipoConteudo() = " + informacaoTipoConteudo.getNuInformacaoTipoConteudo());
				if(informacaoTipoConteudo.getNuInformacaoTipoConteudo().equals(conteudo.getNuInformacaoTipoConteudo())){
					Arquivo arquivoDB = itemConteudoFacade.buscarArquivo(arquivo.getNuArquivo());
					conteudo.setDeConteudo(arquivoDB.getNoArquivo());
					break;
				}
			}
		}
		setItemConteudo(itemConteudo);
		avaliarAcessibilidade(itemConteudo);
		String formulario;
		if(getUsuarioLogado().isModoDesenvolvimento()){
			formulario = FormularioItemConteudo.gerarFormularioHtml(itemConteudo, action,true);
		}else{
			formulario = FormularioItemConteudo.gerarFormularioHtml(itemConteudo, action,false);
		}
		formulario += gerarHtmlRelatorio(itemConteudo);
		setFormEditar(formulario);
	}
	
	/**
	 * Dao que salva em sessao
	 */
	private ItemConteudoDaoTemp itemConteudoDaoTemp;
	
	/**
	 * Dao para salvar temporariamente em sessao
	 * @return ItemConteudoDao
	 */
	public ItemConteudoDaoTemp getItemConteudoDaoTemp() {
		if(itemConteudoDaoTemp==null){
			itemConteudoDaoTemp = new ItemConteudoDaoTemp(getRequest().getSession());
		}
		return itemConteudoDaoTemp;
	}
	
	private List<ItemConteudo> listItemConteudo;
	public void setListItemConteudo(List<ItemConteudo> listItemConteudo) {
		this.listItemConteudo = listItemConteudo;
	}
	public List<ItemConteudo> getListItemConteudo() {
		return this.listItemConteudo;
	}
	
	private ItemConteudo itemConteudo;
	public void setItemConteudo(ItemConteudo itemConteudo) {
		this.itemConteudo = itemConteudo;
	}
	public ItemConteudo getItemConteudo() {
		return itemConteudo;
	}
	
	private String formEditar = "";
	protected void setFormEditar(String formEditar) {
		this.formEditar = formEditar;
	}
	
	private Conteudo conteudo = null;
	
	/**
	 * Flag para saber se carregou do DB
	 */
	private boolean conteudoCarregado = false;
	public BaseItemConteudo(){
		
	}
	
	/**
	 * Lazy, carrega pelo id do conteudo.getNuConteudo()
	 * @return conteudo
	 */
	public Conteudo getConteudo() {
		if(!conteudoCarregado && conteudo!=null){
			conteudo = itemConteudoFacade.buscarConteudo(conteudo.getNuConteudo());
			conteudoCarregado = true;
		}
		return conteudo;
	}
	
	public void setConteudo(Conteudo conteudo) {
		this.conteudo = conteudo;
	}
	
	/**
	 * Verifica se foi enviado um parametro
	 * (normalmente hidden)
	 * com name=isPosted e value=s
	 * @return true caso tenha sido postado
	 */
	protected boolean isPosted(){
		return getRequest().getParameter("isPosted") != null && getRequest().getParameter("isPosted").equals("s");
	}
	
	public String getFormEditar(){
		return formEditar;
	}
	
	/**
	 * Link para publicar o item de conteudo
	 */
	public String getLink() {
		if(itemConteudo==null || itemConteudo.getNuItemConteudo()==null || itemConteudo.getNuItemConteudo().equals(0l)){
			//se nao existe ou o id==0 ou nao tem id, nao faz o link
			return "";
		}
		String retorno="itemConteudo.nuItemConteudo="+itemConteudo.getNuItemConteudo()+"&amp;conteudo.nuConteudo="+conteudo.getNuConteudo();
		SecurityManager sm2=SecurityManager.securityManeger;	
		Usuario usuarioLogado2 = getUsuarioLogado();
		if(itemConteudo.getStSituacao()=='r' || itemConteudo.getStSituacao()=='h'){
			if(sm2.podeExecutarAcao(usuarioLogado2,"publicarItem")){
				return "<b>Deseja&nbsp;<a href=\"publicarItem.action?"+retorno+"\" id=\"btnSituacao\">Publicar</a>?</b>"; 
			}else if(itemConteudo.getStSituacao()=='r'){
				return "<b>Deseja&nbsp;<a href=\"homologarItem.action?"+retorno+"\" id=\"btnSituacao\">Homologar</a>?</b>";
			}
		}else if(itemConteudo.getStSituacao()=='p' && sm2.podeExecutarAcao(usuarioLogado2,"despublicarItemConteudo")){
			return "<b>Deseja&nbsp;<a href=\"despublicarItemConteudo.action?"+retorno+"\" id=\"btnSituacao\">despublicar</a>?</b>";
		}else if(itemConteudo.getStSituacao()=='b' && sm2.podeExecutarAcao(usuarioLogado2,"restaurarItemConteudo")){
			return "<b>Deseja&nbsp;<a href=\"restaurarItemConteudo.action?"+retorno+"\" id=\"btnSituacao\">Restaurar</a>?</b>";
		}
		return "";
	}
	
	/**
	 * Cadastra o item de conteudo no banco
	 * @param itemConteudoPai
	 * @param request
	 * @return Item de conteudo cadastrado, ou null
	 */
	protected ItemConteudo adicionarItem(ItemConteudo itemConteudoPai,HttpServletRequest request) {
		Usuario usuario = getUsuarioLogado();
		ItemConteudo itemConteudo = null;
		try {
			if (request.getParameter("isPosted") != null && request.getParameter("isPosted").equals("s")) {
				itemConteudo = parsePost(request);
				itemConteudoFacade.criar(usuario, itemConteudo,itemConteudoPai);
				getItemConteudoDaoTemp().apagar(itemConteudo);
			}
		} catch (Exception e) {
			usuario.addActionError(e.getMessage());
			logger.error("Erro ao adicionar Item de conteudo", e);
		}
		return itemConteudo;
	}
	
	
	/**
	 * Popula o relatorio de acessibilidade no conteudoFormatado
	 * @param itemConteudo
	 * @return retorna true caso n�o encontre erros
	 */
	public static boolean avaliarAcessibilidade(ItemConteudo itemConteudo) {
		logger.debug("avaliarAcessibilidade iniciado...");
		boolean retorno=true;
		if(itemConteudo.getListConteudoFormatado()==null){
			return true;
		}
		boolean avaliado = false;
		//AsesCliente.setDtdBasePath("http://"+request.getLocalName()+request.getContextPath()+"/dtd");
		for(ConteudoFormatado conteudoFormatado:itemConteudo.getListConteudoFormatado()){
			AsesCliente avaliador = new AsesCliente();
			avaliador.setCorrecaoLinha(-1);
			avaliador.tratar(conteudoFormatado);
			if(conteudoFormatado.getDeConteudo()==null || conteudoFormatado.getDeConteudo().equals("")){
				logger.warn("Campo vazio " +conteudoFormatado.getNuInformacaoTipoConteudo());
			}
			avaliador.avalia(strTemplateParaAvaliacao.replace("{conteudo}",conteudoFormatado.getDeConteudo()));
			avaliado=true;
			if(avaliador.isErrado()){
				retorno=false;
				conteudoFormatado.setRelatorioAcessibilidade(avaliador.getRelatorio());
			}
			//System.out.println("conteudoFormatado.getDeConteudo()="+conteudoFormatado.getDeConteudo());
		}
		if(!avaliado){
			logger.warn("Nenhum campo foi avaliado");
		}
		if(!retorno){
			logger.debug("Erros encontrado, alterando estado");
			itemConteudo.setStSituacao('a');
		}
		logger.debug("avaliarAcessibilidade terminado.");
		return retorno;
	}
	
	/**
	 * Cria um item de conteudo de acordo com o post do request
	 * @param request
	 * @return Item de conteudo
	 * @throws Exception erros de preenchimento
	 */
	public ItemConteudo parsePost(HttpServletRequest request) throws Exception {
		String erro = "";
		try {
			long nu_conteudo = Long.parseLong(request.getParameter("conteudo.nuConteudo"));
			br.org.acessobrasil.portal.modelo.Conteudo conteudo = itemConteudoFacade.buscarConteudo(nu_conteudo);
			ItemConteudo itemConteudo = new ItemConteudo();
			itemConteudo.setNuItemConteudo(0L);
			
			itemConteudo.setNuConteudo(nu_conteudo);
			
			if(conteudo.getTipoConteudo().getPossuiPreco()==1){//verifica se o item deve conter o preco
				if(request.getParameter("preco")==null){
					erro="O campo pre&ccedil;o &eacute; obrigat&oacute;rio";
					throw new Exception(erro);
				}else{
					erro="Digite corretamente o pre&ccedil;o";
					itemConteudo.setPreco(Double.parseDouble(request.getParameter("preco")));
				}
			}			
			itemConteudo.setNoTitulo(request.getParameter("no_titulo"));
			erro = "Digite corretamente a data de publica&ccedil;&atilde;o.";
			itemConteudo.setDtParaPublicacao(Conversor.converteDDMMYYYY(request.getParameter("dt_para_publicacao")));
			erro = "Digite corretamente a data para retirada.";
			itemConteudo.setDtParaRetirada(Conversor.converteDDMMYYYY(request.getParameter("dt_para_retirada")));
			
			ArrayList<ConteudoFormatado> arrConteudoFormatado = new ArrayList<ConteudoFormatado>();
			for (br.org.acessobrasil.portal.modelo.InformacaoTipoConteudo info : conteudo.getTipoConteudo().getListInformacaoTipoConteudo()) {
				if (!info.getCoAtivo()) {
					continue;
				}
				erro = "Preencha corretamente o campo '" + info.getNoInformacao() + "'.";
				long nu_informacao_tipo_conteudo = info.getNuInformacaoTipoConteudo();
				String campoNome = "info" + nu_informacao_tipo_conteudo;
				ConteudoFormatado conteudoFormatado = new ConteudoFormatado();
				
				if (info.getFormato().getClassName() == "java.sql.Date") {
					String val = Conversor.converteDDMMYYYY(request.getParameter(campoNome)).toString();
					conteudoFormatado.setDeConteudo(val);
				} else {
					String val = request.getParameter(campoNome); 
					if(val.equals(info.getDeDicaPreenchimento())) val="";
					conteudoFormatado.setDeConteudo(val);
				}
				conteudoFormatado.setNuInformacaoTipoConteudo(nu_informacao_tipo_conteudo);
				conteudoFormatado.setInformacaoTipoConteudo(info);
				arrConteudoFormatado.add(conteudoFormatado);
			}
			itemConteudo.setListConteudoFormatado(arrConteudoFormatado);
			return itemConteudo;
		} catch (Exception e) {
			throw new Exception(erro);
		}
	}
	
	protected String estaIncluindoImagem(){
		// se o usuario postou trata qual m�todo chamar
		String redireciona = null;
		// n�mero de bot�es de arquivos
		if (getRequest().getParameter("countBtnEscolherArquivo") != null) {
			int countBtnEscolherArquivo = Integer.valueOf(getRequest().getParameter("countBtnEscolherArquivo"));
			// verifica se foi apertado um desses bot�es de arquivo
			for (int i = 0; i < countBtnEscolherArquivo; i++) {
				if (getRequest().getParameter("btnEscolherArquivo" + i) != null) {
					redireciona = getRequest().getParameter("redireciona" + i);
				}
			}
		}
		return redireciona;
	}
	
	protected void redirecionar(String redireciona) throws Exception{
		// est� incluindo um item de imagem, flash, etc
		// ent�o coloca o item temporariamente na sessao
		ItemConteudo itemConteudoRequest = parsePost(getRequest());
		ItemConteudo itemConteudoDB = itemConteudoFacade.buscar(getUsuarioLogado(), itemConteudo.getNuItemConteudo());
		itemConteudoRequest.setStSituacao(itemConteudoDB.getStSituacao());
		itemConteudoRequest.setStSituacaoAnterior(itemConteudoDB.getStSituacaoAnterior());
		itemConteudoRequest.setNuUsuario(itemConteudoDB.getNuUsuario());
		itemConteudoRequest.setNuItemConteudo(Long.valueOf(getRequest().getParameter("itemConteudo.nuItemConteudo")));
		
		getItemConteudoDaoTemp().create(itemConteudoRequest);
		setItemConteudo(itemConteudoRequest);
		getResponse().sendRedirect(redireciona);
	}
	
	protected String gerarHtmlRelatorio(ItemConteudo itemConteudo){
		String retorno="";
		// Gerar o relatorio de acessibilidade
		List<ConteudoFormatado> listConteudoFormatado = itemConteudo.getListConteudoFormatado();
		for(int i=0;listConteudoFormatado!=null && i<listConteudoFormatado.size();i++){
			ConteudoFormatado conteudoFormatado = listConteudoFormatado.get(i);
			if(conteudoFormatado.getInformacaoTipoConteudo()==null){
				logger.warn("formatado.getInformacaoTipoConteudo() = null id = " + conteudoFormatado.getNuInformacaoTipoConteudo());
				try{
					InformacaoTipoConteudo informacaoTipoConteudo = itemConteudoFacade.buscarInformacaoTipoConteudo(conteudoFormatado.getNuInformacaoTipoConteudo());
					conteudoFormatado.setInformacaoTipoConteudo(informacaoTipoConteudo);
				}catch(Exception e){
					logger.error("Erro ao abrir informacao tipo conteudo");
				}
			}
			if(conteudoFormatado.getRelatorioAcessibilidade()!=null && conteudoFormatado.getInformacaoTipoConteudo()!=null && conteudoFormatado.getInformacaoTipoConteudo().getNoInformacao()!=null){
				retorno+="<div class=\"relatorioAcessibilidade\">"+
					"<div class=\"titulo\">"+
					conteudoFormatado.getInformacaoTipoConteudo().getNoInformacao() +
					"</div>" +
					GeraRelatorio.getHtml(conteudoFormatado.getRelatorioAcessibilidade(),"id"+i) +
					"</div>";
			}
		}
		return retorno;
	}
	
	public String getBtnAcessibilizar() {
		return btnAcessibilizar;
	}
	
	public void setBtnAcessibilizar(String btnAcessibilizar) {
		this.btnAcessibilizar = btnAcessibilizar;
	}

	public String getBtnFindAndReplace() {
		return btnFindAndReplace;
	}

	public void setBtnFindAndReplace(String btnFindAndReplace) {
		this.btnFindAndReplace = btnFindAndReplace;
	}
	public String getProcurar() {
		return procurar;
	}
	public void setProcurar(String procurar) {
		this.procurar = procurar;
	}
	public String getSubstituir() {
		return substituir;
	}
	public void setSubstituir(String substituir) {
		this.substituir = substituir;
	}
}